import matplotlib
import numpy as np
from PyQt5 import QtWidgets
from PyQt5.QtCore import Qt, pyqtSignal
from PyQt5.QtWidgets import QLabel, QWidget
from matplotlib.backends.backend_qt5agg import FigureCanvasQTAgg as FigureCanvas
from matplotlib.figure import Figure
from matplotlib.lines import Line2D
from LanguageTool import getCNfromDict

matplotlib.use('Qt5Agg')  # 指定 Matplotlib 使用 PyQt5 后端
# plt.figure(dpi=600) # 将显示的所有图分辨率调高
matplotlib.rc("font", family='SimHei')  # 显示中文
matplotlib.rcParams['axes.unicode_minus'] = False  # 显示符号


class MusicSlider(QWidget):
    crop_signal = pyqtSignal(list)  # 用于发送裁剪信号 list = [vline1_pos, vline2_pos]

    vline1 = None
    vline1_pos = 0  # 初始时间
    vline2 = None
    vline2_pos = 0  # 结束时间
    timeLen = 0

    def __init__(self):
        super().__init__()

        self.setFixedHeight(150)

        # 左边
        self.startTime = QLabel('')
        self.startTime.setMaximumWidth(150)
        self.startTime.setAlignment(Qt.AlignCenter)
        self.setStartTimeLabel()

        # 中间创建一个 Matplotlib Figure
        self.figure = Figure()
        self.figure.patch.set_alpha(0)
        self.figure.subplots_adjust(left=0, right=1, bottom=0, top=1)
        self.canvas = FigureCanvas(self.figure)
        # 添加鼠标事件回调
        self.canvas.mpl_connect('motion_notify_event', self.on_mouse_move)
        self.canvas.mpl_connect('button_press_event', self.on_mouse_press)
        # 绑定鼠标释放事件
        self.canvas.mpl_connect('button_release_event', self.on_mouse_release)
        # self.set_mpl_fig()

        # 右边
        self.endTime = QLabel('')
        self.endTime.setMaximumWidth(150)
        self.endTime.setAlignment(Qt.AlignCenter)
        self.setEndTimeLabel()

        # 创建一个布局，并将画布添加到布局中
        layout = QtWidgets.QHBoxLayout()
        layout.addWidget(self.startTime)
        layout.addWidget(self.canvas)
        layout.addWidget(self.endTime)
        self.setLayout(layout)

        self.selected_line = None

    def setEmpty(self):
        self.vline1 = None
        self.vline1_pos = 0  # 初始时间
        self.vline2 = None
        self.vline2_pos = 0  # 结束时间
        self.timeLen = 0
        self.setStartTimeLabel()
        self.setEndTimeLabel()
        self.figure.clear()
        self.canvas.draw()

    def setStartTimeLabel(self):
        # sec = self.vline1_pos*self.timeLen/1000
        secLabel = "{:02.3f}".format(self.vline1_pos)
        self.startTime.setText(getCNfromDict('TabBar01-tb3-ms_starttime').replace('{T}', secLabel))

    def setEndTimeLabel(self):
        # sec = self.vline2_pos*self.timeLen/1000
        secLabel = "{:02.3f}".format(self.vline2_pos)
        self.endTime.setText(getCNfromDict('TabBar01-tb3-ms_endtime').replace('{T}', secLabel))

    def setTimeLen(self, timeLen):
        self.timeLen = timeLen

    def setFigure(self, audio_data, start_ms, end_ms, totleTime, hz=44100):
        # print(audio_data)
        # print(len(audio_data))
        time = np.arange(0, len(audio_data)) * (1.0 / hz)
        # print(len(time))

        self.vline1 = None
        self.vline2 = None
        self.figure.clear()

        self.vline1_pos = start_ms / 1000
        self.vline2_pos = end_ms / 1000
        # print(self.vline2_pos)
        self.timeLen = totleTime
        self.setStartTimeLabel()
        self.setEndTimeLabel()

        # self.figure = Figure()
        # self.figure.patch.set_alpha(0)
        # self.figure.subplots_adjust(left=0, right=1, bottom=0, top=1)
        # self.canvas = FigureCanvas(self.figure)
        # 创建一个子图并在其中绘制数据

        ax = self.figure.add_subplot(111)
        ax.plot(time, audio_data, antialiased=True)

        self.vline1 = Line2D([self.vline1_pos, self.vline1_pos], [audio_data.min(), audio_data.max()], color='red',
                             linestyle='--', lw=2, alpha=0.8)
        self.vline2 = Line2D([self.vline2_pos, self.vline2_pos], [audio_data.min(), audio_data.max()], color='green',
                             linestyle='--', lw=2, alpha=0.8)
        ax.add_line(self.vline1)
        ax.add_line(self.vline2)

        # 移除边框和坐标轴
        ax.axis('off')
        # 更新画布以显示图表
        self.canvas.draw()

    def on_mouse_press(self, event):
        # 鼠标按下事件
        if self.timeLen == 0:
            return

        # 检查是否点击了辅助线附近
        if event.inaxes:  # 鼠标仅在坐标轴范围内有效
            x = event.xdata
            print(f"x : {x} timeLen: {self.timeLen}")
            print(f"vline1_pos : { self.vline1_pos }")
            print(f"vline2_pos : { self.vline2_pos }")
            if abs(x - self.vline1_pos)/self.timeLen*1000 < 0.02:
                self.selected_line = 'vline1'
            elif abs(x - self.vline2_pos)/self.timeLen*1000 < 0.02:
                self.selected_line = 'vline2'
            else:
                self.selected_line = None

    def on_mouse_move(self, event):
        # 鼠标移动事件
        if self.timeLen == 0:
            return

        if event.inaxes and self.selected_line:  # 鼠标在范围内
            x = event.xdata
            if self.selected_line == 'vline1':  # 拖动红色辅助线
                if 0 <= x < self.vline2_pos:
                    self.vline1.set_xdata([x, x])
                    self.vline1_pos = x
                    self.setStartTimeLabel()
                elif 0 > x:
                    self.vline1.set_xdata([0, 0])
                    self.vline1_pos = 0
                    self.setStartTimeLabel()
            elif self.selected_line == 'vline2':  # 拖动绿色辅助线
                if self.timeLen/1000 >= x > self.vline1_pos:
                    self.vline2.set_xdata([x, x])
                    self.vline2_pos = x
                    self.setEndTimeLabel()
                elif x > self.timeLen/1000:
                    self.vline2.set_xdata([self.timeLen/1000, self.timeLen/1000])
                    self.vline2_pos = self.timeLen/1000
                    self.setEndTimeLabel()

            # 更新画布
            self.canvas.draw()
        elif self.selected_line:
            self.selected_line = None
            # 发送裁剪信号
            self.crop_signal.emit([self.vline1_pos * 1000, self.vline2_pos * 1000])

    def on_mouse_release(self, event):
        # 处理鼠标释放事件
        if self.timeLen == 0:
            return

        if event.inaxes and self.selected_line:  # 确保鼠标在子图范围内
            self.selected_line = None
            # 发送裁剪信号
            self.crop_signal.emit([self.vline1_pos * 1000, self.vline2_pos * 1000])

